package cn.silver.module.authority.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.silver.framework.core.constant.CacheNames;
import cn.silver.framework.core.enums.SystemStatusEnums;
import cn.silver.framework.core.exception.ServiceException;
import cn.silver.framework.core.utils.MapstructUtils;
import cn.silver.framework.mybatis.domain.TreeEntity;
import cn.silver.framework.mybatis.service.impl.DataServiceImpl;
import cn.silver.module.authority.domain.*;
import cn.silver.module.authority.mapper.*;
import cn.silver.module.authority.bean.TenantBean;
import cn.silver.module.authority.param.TenantParam;
import cn.silver.module.authority.service.ISysTenantService;
import cn.silver.module.system.domain.SysDept;
import cn.silver.module.system.domain.SysUser;
import cn.silver.module.system.domain.SysUserRole;
import cn.silver.module.system.enums.RoleTypeEnums;
import cn.silver.module.system.mapper.SysDeptMapper;
import cn.silver.module.system.mapper.SysUserMapper;
import cn.silver.module.system.mapper.SysUserRoleMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 租户Service业务层处理
 *
 * @author Silver Zhou
 */
@Service
@RequiredArgsConstructor
public class SysTenantServiceImpl extends DataServiceImpl<SysTenantMapper, SysTenant, TenantParam, TenantBean> implements ISysTenantService {

    private final SysTenantGroupMapper groupMapper;
    private final SysUserMapper userMapper;
    private final SysDeptMapper deptMapper;
    private final SysRoleMapper roleMapper;
    private final SysRoleMenuMapper roleMenuMapper;
    private final SysRoleDeptMapper roleDeptMapper;
    private final SysUserRoleMapper userRoleMapper;


    @Override
    public void init() {
        List<SysTenant> tenants = this.baseMapper.selectList(new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getCode, SysTenant.DEFALUT_CODE));
        if (CollectionUtils.isEmpty(tenants)) {
            SysTenant defaultTenant = SysTenant.getDefault();
            defaultTenant.preInsert();
            this.baseMapper.insert(defaultTenant);
        }
    }

    /**
     * 基于租户ID查询租户
     */
    @Override
    @Cacheable(cacheNames = CacheNames.SYS_TENANT, key = "#tenantId")
    public TenantBean queryByTenantId(String tenantId) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysTenant>().eq(SysTenant::getCode, tenantId));
    }


//	@Override
//	public Wrapper<SysTenant> buildQueryWrapper(SysTenant entity) {
//		LambdaQueryWrapper<SysTenant> lqw = Wrappers.lambdaQuery();
//		lqw.eq(StringUtils.isNotBlank(entity.getCode()), SysTenant::getCode, entity.getCode());
//		lqw.like(StringUtils.isNotBlank(entity.getName()), SysTenant::getName, entity.getName());
//		lqw.eq(StringUtils.isNotBlank(entity.getGroupId()), SysTenant::getGroupId, entity.getGroupId());
//		lqw.eq(StringUtils.isNotBlank(entity.getStatus()), SysTenant::getStatus, entity.getStatus());
//		lqw.orderByAsc(SysTenant::getId);
//		return lqw;
//	}

    /**
     * 新增租户
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean insert(TenantBean model) {
        SysTenant entity = MapstructUtils.convert(model, SysTenant.class);

//        // 获取所有租户编号
//        List<String> tenantIds = baseMapper.selectObjs(
//            new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr);
//        String tenantId = generateTenantId(tenantIds);
//        add.setTenantId(tenantId);
        entity.preInsert();
        model.setId(entity.getId());
        this.baseMapper.insert(entity);
        // 根据套餐创建角色
        String roleId = createTenantRole(entity.getId(), entity.getGroupId());

        // 创建部门: 公司名是部门名称
        SysDept dept = new SysDept();
//        dept.setTenantId(tenantId);
//        dept.setDeptName(entity.getCompanyName());
        dept.setPid(TreeEntity.ROOT_NODE);
//        dept.setAncestors(Constants.TOP_PARENT_ID.toString());
        deptMapper.insert(dept);
        String deptId = dept.getId();

        // 角色和部门关联表
        SysRoleDept roleDept = new SysRoleDept();
        roleDept.setRoleId(roleId);
        roleDept.setDeptId(deptId);
        roleDeptMapper.insert(roleDept);

        // 创建系统用户
        SysUser user = new SysUser();
//        user.setTenantId(tenantId);
//        user.setUserName(entity.getUsername());
//        user.setNickName(entity.getUsername());
//        user.setPassword(BCrypt.hashpw(entity.getPassword()));
//        user.setDeptId(deptId);
        userMapper.insert(user);
        //新增系统用户后，默认当前用户为部门的负责人
        SysDept sd = new SysDept();
//        sd.setLeader(user.getId());
        sd.setId(deptId);
        deptMapper.updateById(sd);

        // 用户和角色关联表
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(roleId);
        userRoleMapper.insert(userRole);

//        String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
//        List<SysDictType> dictTypeList = dictTypeMapper.selectList(
//            new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
//        List<SysDictData> dictDataList = dictDataMapper.selectList(
//            new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
//        for (SysDictType dictType : dictTypeList) {
//            dictType.setId(null);
//            dictType.setTenantId(tenantId);
//        }
//        for (SysDictData dictData : dictDataList) {
//            dictData.setDictCode(null);
//            dictData.setTenantId(tenantId);
//        }
//        dictTypeMapper.insertBatch(dictTypeList);
//        dictDataMapper.insertBatch(dictDataList);

//        List<SysParam> sysParamList = configMapper.selectList(
//            new LambdaQueryWrapper<SysParam>().eq(SysParam::getTenantId, defaultTenantId));
//        for (SysParam config : sysParamList) {
//            config.setId(null);
//            config.setTenantId(tenantId);
//        }
//        configMapper.insertBatch(sysParamList);
        return true;
    }

    /**
     * 根据租户菜单创建租户角色
     *
     * @param tenantId  租户编号
     * @param packageId 租户套餐id
     * @return 角色id
     */
    private String createTenantRole(String tenantId, String packageId) {
        // 获取租户套餐
        SysTenantGroup tenantPackage = groupMapper.selectById(packageId);
        if (ObjectUtil.isNull(tenantPackage)) {
            throw new ServiceException("套餐不存在");
        }
        // 获取套餐菜单id
//        List<String> menuIds = StringUtils.splitTo(tenantPackage.g(), Convert::toStr);
        List<String> menuIds = Collections.EMPTY_LIST;
        // 创建角色
        SysRole role = new SysRole();
//        role.setTenantId(tenantId);
        role.setName(tenantPackage.getName() + "管理员");
        role.setCode(tenantPackage.getCode());
//        role.setS(1);
        role.setStatus(SystemStatusEnums.NORMAL.getCode());
        roleMapper.insert(role);
        String roleId = role.getId();

        // 创建角色菜单
        List<SysRoleMenu> roleMenus = new ArrayList<>(menuIds.size());
        menuIds.forEach(menuId -> {
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenus.add(roleMenu);
        });
        roleMenuMapper.insertBatch(roleMenus);

        return roleId;
    }

    /**
     * 同步租户套餐
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Boolean syncTenantPackage(String tenantId, String packageId) {
        SysTenantGroup tenantPackage = groupMapper.selectById(packageId);
        List<SysRole> roles = roleMapper.selectList(
                new LambdaQueryWrapper<SysRole>().eq(SysRole::getBusId, tenantId));
        List<String> roleIds = new ArrayList<>(roles.size() - 1);
//        List<String> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toStr);
        List menuIds = Collections.EMPTY_LIST;
        roles.forEach(item -> {
            if (RoleTypeEnums.TENANT_ROLE.getCode().equals(item.getType())) {
                List<SysRoleMenu> roleMenus = new ArrayList<>(0);
                menuIds.forEach(menuId -> {
                    SysRoleMenu roleMenu = new SysRoleMenu();
                    roleMenu.setRoleId(item.getId());
                    roleMenu.setMenuId((String) menuId);
                    roleMenus.add(roleMenu);
                });
                roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, item.getId()));
                roleMenuMapper.insertBatch(roleMenus);
            } else {
                roleIds.add(item.getId());
            }
        });
        if (!roleIds.isEmpty()) {
            roleMenuMapper.delete(
                    new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(false, SysRoleMenu::getMenuId, menuIds));
        }
        return true;
    }
}
